﻿2026-05-13T07:06:58.9207070Z ##[group]Run pnpm verify:phase-4
2026-05-13T07:06:58.9207428Z [36;1mpnpm verify:phase-4[0m
2026-05-13T07:06:58.9229549Z shell: /usr/bin/bash -e {0}
2026-05-13T07:06:58.9229814Z env:
2026-05-13T07:06:58.9230071Z   PNPM_HOME: /home/runner/setup-pnpm/node_modules/.bin
2026-05-13T07:06:58.9230413Z   SKIP_PHASE_3_CARRYOVER: 1
2026-05-13T07:06:58.9230647Z   SKIP_TRACE_CHECK: 1
2026-05-13T07:06:58.9230859Z ##[endgroup]
2026-05-13T07:06:59.2380807Z 
2026-05-13T07:06:59.2381695Z > rebno@0.0.0 verify:phase-4 /home/runner/work/rebno/rebno
2026-05-13T07:06:59.2382801Z > node scripts/verify-phase-4.mjs
2026-05-13T07:06:59.2383540Z 
2026-05-13T07:06:59.2748289Z 
2026-05-13T07:06:59.2749349Z === Workspace: typecheck ===
2026-05-13T07:06:59.2750416Z >>> pnpm -r typecheck
2026-05-13T07:06:59.6269333Z Scope: 5 of 6 workspace projects
2026-05-13T07:06:59.6325924Z packages/db typecheck$ tsc --noEmit
2026-05-13T07:06:59.6335009Z packages/game-logic typecheck$ tsc --noEmit
2026-05-13T07:07:02.1486844Z packages/game-logic typecheck: Done
2026-05-13T07:07:02.1518932Z packages/protocol typecheck$ tsc --noEmit
2026-05-13T07:07:04.5132176Z packages/db typecheck: Done
2026-05-13T07:07:05.6971271Z packages/protocol typecheck: Done
2026-05-13T07:07:05.6978802Z apps/client typecheck$ tsc --noEmit
2026-05-13T07:07:05.6998559Z apps/server typecheck$ tsc --noEmit
2026-05-13T07:07:17.5579021Z apps/client typecheck: Done
2026-05-13T07:07:18.0429809Z apps/server typecheck: Done
2026-05-13T07:07:18.0537436Z 
2026-05-13T07:07:18.0541993Z === Lint: protocol-sync ===
2026-05-13T07:07:18.0542766Z >>> pnpm lint:protocol-sync
2026-05-13T07:07:18.3625854Z 
2026-05-13T07:07:18.3627010Z > rebno@0.0.0 lint:protocol-sync /home/runner/work/rebno/rebno
2026-05-13T07:07:18.3628750Z > node tools/scripts/lint-protocol-sync.mjs
2026-05-13T07:07:18.3629417Z 
2026-05-13T07:07:18.3948061Z lint-protocol-sync: OK
2026-05-13T07:07:18.4075543Z 
2026-05-13T07:07:18.4076465Z === Lint: game-logic-purity ===
2026-05-13T07:07:18.4077384Z >>> pnpm lint:game-logic-purity
2026-05-13T07:07:18.7151459Z 
2026-05-13T07:07:18.7152595Z > rebno@0.0.0 lint:game-logic-purity /home/runner/work/rebno/rebno
2026-05-13T07:07:18.7153900Z > node tools/scripts/lint-game-logic-purity.mjs
2026-05-13T07:07:18.7154617Z 
2026-05-13T07:07:18.7474075Z lint-game-logic-purity: OK (7 file(s) clean)
2026-05-13T07:07:18.7590625Z 
2026-05-13T07:07:18.7591316Z === Lint: better-auth-schema-sync ===
2026-05-13T07:07:18.7592363Z >>> pnpm lint:better-auth-schema-sync
2026-05-13T07:07:19.0647122Z 
2026-05-13T07:07:19.0648585Z > rebno@0.0.0 lint:better-auth-schema-sync /home/runner/work/rebno/rebno
2026-05-13T07:07:19.0650013Z > node tools/scripts/lint-better-auth-schema-sync.mjs
2026-05-13T07:07:19.0650643Z 
2026-05-13T07:07:20.7214673Z lint-better-auth-schema-sync: OK
2026-05-13T07:07:20.7346205Z 
2026-05-13T07:07:20.7346640Z === Lint: rate-limit-budgets ===
2026-05-13T07:07:20.7347049Z >>> pnpm lint:rate-limit-budgets
2026-05-13T07:07:21.0386222Z 
2026-05-13T07:07:21.0386953Z > rebno@0.0.0 lint:rate-limit-budgets /home/runner/work/rebno/rebno
2026-05-13T07:07:21.0387513Z > node tools/scripts/lint-rate-limit-budgets.mjs
2026-05-13T07:07:21.0387751Z 
2026-05-13T07:07:21.0699292Z lint-rate-limit-budgets: OK (5 D-22 budgets locked)
2026-05-13T07:07:21.0828644Z 
2026-05-13T07:07:21.0840129Z === Lint: no-clipboard-rce ===
2026-05-13T07:07:21.0858811Z >>> pnpm lint:no-clipboard-rce
2026-05-13T07:07:21.3893975Z 
2026-05-13T07:07:21.3895103Z > rebno@0.0.0 lint:no-clipboard-rce /home/runner/work/rebno/rebno
2026-05-13T07:07:21.3896223Z > node tools/scripts/lint-no-clipboard-rce.mjs
2026-05-13T07:07:21.3896798Z 
2026-05-13T07:07:21.4228145Z lint-no-clipboard-rce: OK (21 file(s) clean)
2026-05-13T07:07:21.4354353Z 
2026-05-13T07:07:21.4354884Z === Lint: room-layout ===
2026-05-13T07:07:21.4355532Z >>> pnpm lint:room-layout
2026-05-13T07:07:21.7403634Z 
2026-05-13T07:07:21.7404732Z > rebno@0.0.0 lint:room-layout /home/runner/work/rebno/rebno
2026-05-13T07:07:21.7406315Z > node tools/scripts/lint-room-layout.mjs
2026-05-13T07:07:21.7407220Z 
2026-05-13T07:07:21.7774060Z lint-room-layout: OK
2026-05-13T07:07:21.7897005Z 
2026-05-13T07:07:21.7897491Z === ADR 0004 lint ===
2026-05-13T07:07:21.7898647Z >>> pnpm lint:adr:0004
2026-05-13T07:07:22.0992215Z 
2026-05-13T07:07:22.0993281Z > rebno@0.0.0 lint:adr:0004 /home/runner/work/rebno/rebno
2026-05-13T07:07:22.0994667Z > node tools/asset-catalog/scripts/lint-adr.mjs docs/adr/0004-room-hot-reload.md --no-matrix
2026-05-13T07:07:22.0995526Z 
2026-05-13T07:07:22.1283207Z OK: ADR docs/adr/0004-room-hot-reload.md validated (no-matrix mode — Michael Nygard sections present)
2026-05-13T07:07:22.1395411Z 
2026-05-13T07:07:22.1395915Z === Drizzle: emit-check ===
2026-05-13T07:07:22.1396577Z >>> pnpm db:emit-check
2026-05-13T07:07:22.4433472Z 
2026-05-13T07:07:22.4434534Z > rebno@0.0.0 db:emit-check /home/runner/work/rebno/rebno
2026-05-13T07:07:22.4437498Z > pnpm -C packages/db exec drizzle-kit generate && node -e "require('fs').copyFileSync('packages/db/migrations/0001_baseline.sql','docs/extracted-server/0001_baseline.sql')" && git diff --exit-code packages/db/migrations/0001_baseline.sql docs/extracted-server/0001_baseline.sql
2026-05-13T07:07:22.4439937Z 
2026-05-13T07:07:22.9002694Z No config path provided, using default 'drizzle.config.ts'
2026-05-13T07:07:22.9005371Z Reading config file '/home/runner/work/rebno/rebno/packages/db/drizzle.config.ts'
2026-05-13T07:07:23.3261400Z 8 tables
2026-05-13T07:07:23.3262181Z accounts 8 columns 1 indexes 0 fks
2026-05-13T07:07:23.3263151Z audit_log 6 columns 0 indexes 2 fks
2026-05-13T07:07:23.3263988Z characters 9 columns 0 indexes 1 fks
2026-05-13T07:07:23.3267059Z inventory_items 4 columns 0 indexes 1 fks
2026-05-13T07:07:23.3268302Z legacy_credentials_staging 6 columns 0 indexes 0 fks
2026-05-13T07:07:23.3269329Z message_board_replies 5 columns 0 indexes 2 fks
2026-05-13T07:07:23.3270259Z message_board_topics 7 columns 0 indexes 1 fks
2026-05-13T07:07:23.3271038Z sessions 5 columns 0 indexes 1 fks
2026-05-13T07:07:23.3271516Z 
2026-05-13T07:07:23.3272298Z No schema changes, nothing to migrate 😴
2026-05-13T07:07:23.6790671Z 
2026-05-13T07:07:23.6791510Z === Drizzle: schema-sync ===
2026-05-13T07:07:23.6792251Z >>> pnpm lint:schema-sync
2026-05-13T07:07:23.9826169Z 
2026-05-13T07:07:23.9827312Z > rebno@0.0.0 lint:schema-sync /home/runner/work/rebno/rebno
2026-05-13T07:07:23.9831313Z > node -e "const a=require('fs').readFileSync('packages/db/migrations/0001_baseline.sql');const b=require('fs').readFileSync('docs/extracted-server/0001_baseline.sql');if(Buffer.compare(a,b)!==0){console.error('docs/extracted-server/0001_baseline.sql out of sync with packages/db/migrations/0001_baseline.sql');process.exit(1)}console.log('OK')"
2026-05-13T07:07:23.9833921Z 
2026-05-13T07:07:24.0091768Z OK
2026-05-13T07:07:24.0236602Z 
2026-05-13T07:07:24.0250243Z === Drizzle: source-comments ===
2026-05-13T07:07:24.0251193Z >>> pnpm lint:source-comments
2026-05-13T07:07:24.3498758Z 
2026-05-13T07:07:24.3510075Z > rebno@0.0.0 lint:source-comments /home/runner/work/rebno/rebno
2026-05-13T07:07:24.3515323Z > pnpm -C packages/db run lint:source-comments
2026-05-13T07:07:24.3529140Z 
2026-05-13T07:07:24.6769156Z 
2026-05-13T07:07:24.6770477Z > @rebno/db@0.1.0 lint:source-comments /home/runner/work/rebno/rebno/packages/db
2026-05-13T07:07:24.6771828Z > node scripts/check-source-comments.mjs
2026-05-13T07:07:24.6772493Z 
2026-05-13T07:07:24.7085211Z check-source-comments: OK (50 columns, all SOURCE-cited)
2026-05-13T07:07:24.7293905Z 
2026-05-13T07:07:24.7294659Z === Workspace: test ===
2026-05-13T07:07:24.7295404Z >>> pnpm -r test
2026-05-13T07:07:25.0448333Z Scope: 5 of 6 workspace projects
2026-05-13T07:07:25.0504936Z packages/db test$ vitest run
2026-05-13T07:07:25.0514076Z packages/game-logic test$ vitest run
2026-05-13T07:07:25.5405663Z packages/db test: [1m[30m[46m RUN [49m[39m[22m [36mv4.1.5 [39m[90m/home/runner/work/rebno/rebno/packages/db[39m
2026-05-13T07:07:25.5897038Z packages/game-logic test: [1m[30m[46m RUN [49m[39m[22m [36mv4.1.5 [39m[90m/home/runner/work/rebno/rebno/packages/game-logic[39m
2026-05-13T07:07:26.0510337Z packages/game-logic test:  [32m✓[39m test/step-bno-fidelity.test.ts [2m([22m[2m13 tests[22m[2m)[22m[32m 14[2mms[22m[39m
2026-05-13T07:07:26.2866202Z packages/game-logic test:  [32m✓[39m test/wall-slide.test.ts [2m([22m[2m1 test[22m[2m)[22m[32m 5[2mms[22m[39m
2026-05-13T07:07:26.5087604Z packages/game-logic test:  [32m✓[39m test/golden.test.ts [2m([22m[2m6 tests[22m[2m)[22m[32m 13[2mms[22m[39m
2026-05-13T07:07:26.5670142Z packages/db test:  [32m✓[39m tests/promotion.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 9[2mms[22m[39m
2026-05-13T07:07:26.7694810Z packages/game-logic test:  [32m✓[39m test/walkable-edge.test.ts [2m([22m[2m1 test[22m[2m)[22m[32m 6[2mms[22m[39m
2026-05-13T07:07:26.7960219Z packages/db test:  [32m✓[39m tests/save-format-traceability.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m 8[2mms[22m[39m
2026-05-13T07:07:27.0010350Z packages/game-logic test:  [32m✓[39m test/movement-constants.test.ts [2m([22m[2m9 tests[22m[2m)[22m[32m 8[2mms[22m[39m
2026-05-13T07:07:27.2310140Z packages/game-logic test:  [32m✓[39m test/platform-cycle.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 17[2mms[22m[39m
2026-05-13T07:07:27.4510375Z packages/game-logic test:  [32m✓[39m test/navi-mask-bbox.test.ts [2m([22m[2m2 tests[22m[2m)[22m[32m 7[2mms[22m[39m
2026-05-13T07:07:27.6150276Z packages/db test:  [32m✓[39m tests/schema-shape.test.ts [2m([22m[2m10 tests[22m[2m)[22m[32m 13[2mms[22m[39m
2026-05-13T07:07:27.6206238Z packages/db test: [2m Test Files [22m [1m[32m3 passed[39m[22m[90m (3)[39m
2026-05-13T07:07:27.6221908Z packages/db test: [2m      Tests [22m [1m[32m22 passed[39m[22m[90m (22)[39m
2026-05-13T07:07:27.6238885Z packages/db test: [2m   Start at [22m 07:07:25
2026-05-13T07:07:27.6254407Z packages/db test: [2m   Duration [22m 2.07s[2m (transform 148ms, setup 0ms, import 1.43s, tests 29ms, environment 1ms)[22m
2026-05-13T07:07:27.6500737Z packages/db test: Done
2026-05-13T07:07:27.6513939Z packages/protocol test$ vitest run
2026-05-13T07:07:27.6834104Z packages/game-logic test:  [32m✓[39m test/accumulator.test.ts [2m([22m[2m7 tests[22m[2m)[22m[32m 7[2mms[22m[39m
2026-05-13T07:07:27.9506495Z packages/game-logic test:  [32m✓[39m test/run-speed.test.ts [2m([22m[2m3 tests[22m[2m)[22m[32m 12[2mms[22m[39m
2026-05-13T07:07:28.1720377Z packages/protocol test: [1m[30m[46m RUN [49m[39m[22m [36mv4.1.5 [39m[90m/home/runner/work/rebno/rebno/packages/protocol[39m
2026-05-13T07:07:28.1797703Z packages/game-logic test:  [32m✓[39m test/rng.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 8[2mms[22m[39m
2026-05-13T07:07:28.1980175Z packages/game-logic test: [2m Test Files [22m [1m[32m10 passed[39m[22m[90m (10)[39m
2026-05-13T07:07:28.1992825Z packages/game-logic test: [2m      Tests [22m [1m[32m50 passed[39m[22m[90m (50)[39m
2026-05-13T07:07:28.1999161Z packages/game-logic test: [2m   Start at [22m 07:07:25
2026-05-13T07:07:28.2001186Z packages/game-logic test: [2m   Duration [22m 2.59s[2m (transform 246ms, setup 0ms, import 464ms, tests 98ms, environment 2ms)[22m
2026-05-13T07:07:28.2339413Z packages/game-logic test: Done
2026-05-13T07:07:28.4852022Z packages/protocol test:  [32m✓[39m test/codec.test.ts [2m([22m[2m18 tests[22m[2m)[22m[32m 15[2mms[22m[39m
2026-05-13T07:07:28.6469933Z packages/protocol test:  [32m✓[39m test/intents.test.ts [2m([22m[2m6 tests[22m[2m)[22m[32m 7[2mms[22m[39m
2026-05-13T07:07:28.8109257Z packages/protocol test:  [32m✓[39m test/schema-shape.test.ts [2m([22m[2m3 tests[22m[2m)[22m[32m 5[2mms[22m[39m
2026-05-13T07:07:28.9646451Z packages/protocol test:  [32m✓[39m test/state.test.ts [2m([22m[2m3 tests[22m[2m)[22m[32m 4[2mms[22m[39m
2026-05-13T07:07:28.9707359Z packages/protocol test: [2m Test Files [22m [1m[32m4 passed[39m[22m[90m (4)[39m
2026-05-13T07:07:28.9729800Z packages/protocol test: [2m      Tests [22m [1m[32m30 passed[39m[22m[90m (30)[39m
2026-05-13T07:07:28.9731822Z packages/protocol test: [2m   Start at [22m 07:07:28
2026-05-13T07:07:28.9733995Z packages/protocol test: [2m   Duration [22m 789ms[2m (transform 121ms, setup 0ms, import 226ms, tests 31ms, environment 0ms)[22m
2026-05-13T07:07:29.0006677Z packages/protocol test: Done
2026-05-13T07:07:29.0028807Z apps/client test$ vitest run --exclude 'test/e2e/**'
2026-05-13T07:07:29.0033623Z apps/server test$ vitest run --exclude 'test/**/*.integ.test.ts'
2026-05-13T07:07:29.5347660Z apps/server test: [1m[30m[46m RUN [49m[39m[22m [36mv4.1.5 [39m[90m/home/runner/work/rebno/rebno/apps/server[39m
2026-05-13T07:07:29.6030102Z apps/client test: [1m[46m RUN [49m[22m [36mv3.2.4 [39m[90m/home/runner/work/rebno/rebno/apps/client[39m
2026-05-13T07:07:30.7087357Z apps/server test:  [32m✓[39m test/persistence.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m 58[2mms[22m[39m
2026-05-13T07:07:31.0390054Z apps/server test:  [32m✓[39m test/rate-limit.test.ts [2m([22m[2m7 tests[22m[2m)[22m[32m 14[2mms[22m[39m
2026-05-13T07:07:31.4394885Z apps/server test:  [32m✓[39m test/room-key.test.ts [2m([22m[2m7 tests[22m[2m)[22m[32m 21[2mms[22m[39m
2026-05-13T07:07:31.5600913Z apps/client test: [90mstderr[2m | src/__test__/game-scene.test.ts[2m > [22m[2mscenes/GameScene[2m > [22m[2mtest 5: onRoomLayout calls verifyRoomLayout first; render skipped on false
2026-05-13T07:07:31.5639698Z apps/client test: [22m[39mroom_layout signature did not verify — rendering anyway (defense-in-depth; see 06.1-D40-SPIKE.md) mvp-lobby 000
2026-05-13T07:07:31.6401034Z apps/client test:  [32m✓[39m src/__test__/game-scene.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m 251[2mms[22m[39m
2026-05-13T07:07:31.6960102Z apps/server test: {"level":40,"time":1778656051691,"pid":3310,"hostname":"runnervmeorf1","path":"/api/foo","msg":"staging_invite_rejected"}
2026-05-13T07:07:31.7003773Z apps/server test:  [32m✓[39m test/staging-invite.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m 12[2mms[22m[39m
2026-05-13T07:07:31.7050187Z apps/server test: {"level":40,"time":1778656051694,"pid":3310,"hostname":"runnervmeorf1","path":"/api/foo","msg":"staging_invite_rejected"}
2026-05-13T07:07:31.7088441Z apps/server test: {"level":40,"time":1778656051695,"pid":3310,"hostname":"runnervmeorf1","path":"/api/foo","msg":"staging_invite_rejected"}
2026-05-13T07:07:32.6201459Z apps/server test: {"level":30,"time":1778656052615,"pid":3327,"hostname":"runnervmeorf1","password":"[Redacted]","session_token":"[Redacted]","msg":"login"}
2026-05-13T07:07:32.6239710Z apps/server test:  [32m✓[39m test/otel-init.test.ts [2m([22m[2m4 tests[22m[2m)[22m[33m 684[2mms[22m[39m
2026-05-13T07:07:32.6259244Z apps/server test:      [33m[2m✓[22m[39m does not throw when OTEL_EXPORTER_OTLP_ENDPOINT is unset [33m 560[2mms[22m[39m
2026-05-13T07:07:32.8307745Z apps/client test:  [32m✓[39m src/__test__/sprite-state-machine.test.ts [2m([22m[2m29 tests[22m[2m)[22m[32m 12[2mms[22m[39m
2026-05-13T07:07:33.5890926Z apps/server test: [90mstdout[2m | test/run-migrations.test.ts[2m > [22m[2mrun-migrations.ts (Plan 12)[2m > [22m[2mScenario 1: fresh DB — migrate creates accounts table and records migration row
2026-05-13T07:07:33.5919496Z apps/server test: [22m[39m[run-migrations] opening /tmp/rebno-migrate-test-IaYaSC/rebno.db
2026-05-13T07:07:33.5921196Z apps/server test: [run-migrations] migrationsFolder=/home/runner/work/rebno/rebno/packages/db/migrations
2026-05-13T07:07:33.5922297Z apps/server test: [run-migrations] OK
2026-05-13T07:07:33.6030601Z apps/server test: [90mstdout[2m | test/run-migrations.test.ts[2m > [22m[2mrun-migrations.ts (Plan 12)[2m > [22m[2mScenario 2: pre-bootstrapped DB (Assumption A7) — reconcile seeds row before migrate runs
2026-05-13T07:07:33.6033575Z apps/server test: [22m[39m[run-migrations] opening /tmp/rebno-migrate-test-T14j8e/rebno.db
2026-05-13T07:07:33.6047572Z apps/server test: [run-migrations] migrationsFolder=/home/runner/work/rebno/rebno/packages/db/migrations
2026-05-13T07:07:33.6051524Z apps/server test: [run-migrations] reconciled __drizzle_migrations for pre-bootstrap DB (Assumption A7) — seeded 0001_baseline
2026-05-13T07:07:33.6075761Z apps/server test: [run-migrations] OK
2026-05-13T07:07:33.6094008Z apps/server test: [90mstdout[2m | test/run-migrations.test.ts[2m > [22m[2mrun-migrations.ts (Plan 12)[2m > [22m[2mScenario 3: idempotent second run — no error, no extra rows
2026-05-13T07:07:33.6109311Z apps/server test: [22m[39m[run-migrations] opening /tmp/rebno-migrate-test-8CS0zK/rebno.db
2026-05-13T07:07:33.6131105Z apps/server test: [run-migrations] migrationsFolder=/home/runner/work/rebno/rebno/packages/db/migrations
2026-05-13T07:07:33.6143980Z apps/server test: [run-migrations] OK
2026-05-13T07:07:33.6146493Z apps/server test: [90mstdout[2m | test/run-migrations.test.ts[2m > [22m[2mrun-migrations.ts (Plan 12)[2m > [22m[2mScenario 3: idempotent second run — no error, no extra rows
2026-05-13T07:07:33.6149723Z apps/server test: [22m[39m[run-migrations] opening /tmp/rebno-migrate-test-8CS0zK/rebno.db
2026-05-13T07:07:33.6152182Z apps/server test: [run-migrations] migrationsFolder=/home/runner/work/rebno/rebno/packages/db/migrations
2026-05-13T07:07:33.6154670Z apps/server test: [run-migrations] OK
2026-05-13T07:07:33.6212991Z apps/server test:  [32m✓[39m test/run-migrations.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 57[2mms[22m[39m
2026-05-13T07:07:33.9119933Z apps/server test:  [32m✓[39m test/log.test.ts [2m([22m[2m2 tests[22m[2m)[22m[32m 16[2mms[22m[39m
2026-05-13T07:07:33.9960041Z apps/client test:  [32m✓[39m src/__test__/login-scene.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m 18[2mms[22m[39m
2026-05-13T07:07:34.1556894Z apps/server test:  [32m✓[39m test/admin-stubs.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 18[2mms[22m[39m
2026-05-13T07:07:34.4405256Z apps/server test:  [32m✓[39m test/legacy-login.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m 14[2mms[22m[39m
2026-05-13T07:07:34.6647674Z apps/server test:  [32m✓[39m test/health.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 7[2mms[22m[39m
2026-05-13T07:07:35.3124059Z apps/client test:  [32m✓[39m src/__test__/colyseus-client.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m 17[2mms[22m[39m
2026-05-13T07:07:35.5620888Z apps/server test: [90mstdout[2m | test/tick-accumulator.test.ts
2026-05-13T07:07:35.5622876Z apps/server test: [22m[39m◇ injected env (50) from ../../../../../../../etc/environment // tip: ⌘ override existing { override: true }
2026-05-13T07:07:35.5624567Z apps/server test: ℹ️  optional .env file not found: .env.test, .env
2026-05-13T07:07:36.3183616Z apps/server test:  [32m✓[39m test/tick-accumulator.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m 10[2mms[22m[39m
2026-05-13T07:07:36.3259054Z apps/server test: [2m Test Files [22m [1m[32m11 passed[39m[22m[90m (11)[39m
2026-05-13T07:07:36.3260639Z apps/server test: [2m      Tests [22m [1m[32m61 passed[39m[22m[90m (61)[39m
2026-05-13T07:07:36.3271699Z apps/server test: [2m   Start at [22m 07:07:29
2026-05-13T07:07:36.3273428Z apps/server test: [2m   Duration [22m 6.77s[2m (transform 508ms, setup 0ms, import 3.41s, tests 912ms, environment 2ms)[22m
2026-05-13T07:07:36.3684930Z apps/server test: Done
2026-05-13T07:07:36.3875497Z apps/client test:  [32m✓[39m src/__test__/nameplate.test.ts [2m([22m[2m10 tests[22m[2m)[22m[32m 48[2mms[22m[39m
2026-05-13T07:07:37.0640939Z apps/client test:  [32m✓[39m src/__test__/input-dispatcher.test.ts [2m([22m[2m12 tests[22m[2m)[22m[32m 16[2mms[22m[39m
2026-05-13T07:07:37.8072833Z apps/client test:  [32m✓[39m src/__test__/reconnect.test.ts [2m([22m[2m13 tests[22m[2m)[22m[32m 69[2mms[22m[39m
2026-05-13T07:07:38.5449348Z apps/client test:  [32m✓[39m src/__test__/chat-hud.test.ts [2m([22m[2m9 tests[22m[2m)[22m[32m 85[2mms[22m[39m
2026-05-13T07:07:39.2322465Z apps/client test:  [32m✓[39m src/__test__/nameplate-color.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m 33[2mms[22m[39m
2026-05-13T07:07:39.9570445Z apps/client test:  [32m✓[39m src/__test__/force-reset-overlay.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m 73[2mms[22m[39m
2026-05-13T07:07:40.6990463Z apps/client test:  [32m✓[39m src/__test__/esc-menu.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m 76[2mms[22m[39m
2026-05-13T07:07:41.4311804Z apps/client test:  [32m✓[39m src/__test__/background-renderer.test.ts [2m([22m[2m7 tests[22m[2m)[22m[32m 83[2mms[22m[39m
2026-05-13T07:07:42.1018931Z apps/client test:  [31m❯[39m src/__test__/prediction.test.ts [2m([22m[2m6 tests[22m[2m | [22m[31m2 failed[39m[2m)[22m[32m 10[2mms[22m[39m
2026-05-13T07:07:42.1025911Z apps/client test:    [32m✓[39m PredictionEngine[2m > [22menqueueInput appends to ring buffer with monotonic seq[32m 2[2mms[22m[39m
2026-05-13T07:07:42.1029380Z apps/client test:    [32m✓[39m PredictionEngine[2m > [22mpredictTick advances localState via step() using latest enqueued input[32m 1[2mms[22m[39m
2026-05-13T07:07:42.1032535Z apps/client test: [31m   [31m×[31m PredictionEngine[2m > [22mpredictTick after ack-and-empty-queue applies pure friction decay[39m[32m 4[2mms[22m[39m
2026-05-13T07:07:42.1034820Z apps/client test: [31m     → expected 0 to be greater than 0[39m
2026-05-13T07:07:42.1036884Z apps/client test:    [32m✓[39m PredictionEngine[2m > [22mring buffer trims at MAX_UNACKED_INPUTS[32m 0[2mms[22m[39m
2026-05-13T07:07:42.1039840Z apps/client test: [31m   [31m×[31m PredictionEngine[2m > [22mapplyServerSnapshot replays unacked inputs forward from snapshot[39m[32m 1[2mms[22m[39m
2026-05-13T07:07:42.1042150Z apps/client test: [31m     → expected 0 to be greater than 0[39m
2026-05-13T07:07:42.1044868Z apps/client test:    [32m✓[39m PredictionEngine[2m > [22mapplyServerSnapshot with rolling-back last_input_seq detects server reset (RESEARCH §Pitfall 2)[32m 0[2mms[22m[39m
2026-05-13T07:07:42.7724221Z apps/client test:  [32m✓[39m src/__test__/extrapolation.test.ts [2m([22m[2m7 tests[22m[2m)[22m[32m 5[2mms[22m[39m
2026-05-13T07:07:43.4573719Z apps/client test:  [32m✓[39m src/__test__/reconciler.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 6[2mms[22m[39m
2026-05-13T07:07:44.1191190Z apps/client test:  [32m✓[39m src/__test__/sprite-state-rate.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m 4[2mms[22m[39m
2026-05-13T07:07:44.7891348Z apps/client test:  [32m✓[39m src/__test__/room-layout-verify.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 9[2mms[22m[39m
2026-05-13T07:07:45.4575944Z apps/client test:  [32m✓[39m src/__test__/input-dispatcher-shift.test.ts [2m([22m[2m3 tests[22m[2m)[22m[32m 8[2mms[22m[39m
2026-05-13T07:07:46.1285877Z apps/client test:  [32m✓[39m src/__test__/auth-client.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m 7[2mms[22m[39m
2026-05-13T07:07:46.7902244Z apps/client test:  [32m✓[39m src/__test__/room-collision-bottom-edge.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m 6[2mms[22m[39m
2026-05-13T07:07:47.4810187Z apps/client test:  [32m✓[39m src/__test__/depth-set.test.ts [2m([22m[2m7 tests[22m[2m)[22m[32m 4[2mms[22m[39m
2026-05-13T07:07:48.1538777Z apps/client test:  [32m✓[39m src/__test__/atlas-loader.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 8[2mms[22m[39m
2026-05-13T07:07:48.8237604Z apps/client test:  [32m✓[39m src/__test__/protocol-version-check.test.ts [2m([22m[2m7 tests[22m[2m)[22m[32m 5[2mms[22m[39m
2026-05-13T07:07:49.5059240Z apps/client test:  [32m✓[39m src/__test__/env.test.ts [2m([22m[2m5 tests[22m[2m | [22m[33m4 skipped[39m[2m)[22m[32m 4[2mms[22m[39m
2026-05-13T07:07:49.5300240Z apps/client test: [31m⎯⎯⎯⎯⎯⎯⎯[39m[1m[41m Failed Tests 2 [49m[22m[31m⎯⎯⎯⎯⎯⎯⎯[39m
2026-05-13T07:07:49.5311208Z apps/client test: [41m[1m FAIL [22m[49m src/__test__/prediction.test.ts[2m > [22mPredictionEngine[2m > [22mpredictTick after ack-and-empty-queue applies pure friction decay
2026-05-13T07:07:49.5322515Z apps/client test: [31m[1mAssertionError[22m: expected 0 to be greater than 0[39m
2026-05-13T07:07:49.5339272Z apps/client test: [36m [2m❯[22m src/__test__/prediction.test.ts:[2m62:20[22m[39m
2026-05-13T07:07:49.5399679Z apps/client test:     [90m 60| [39m    p[33m.[39m[34mpredictTick[39m([33mFLAT_LAYOUT[39m)[33m;[39m
2026-05-13T07:07:49.5419559Z apps/client test:     [90m 61| [39m    [35mconst[39m mid [33m=[39m { [33m...[39mp[33m.[39m[34mgetLocalState[39m() }[33m;[39m
2026-05-13T07:07:49.5439505Z apps/client test:     [90m 62| [39m    [34mexpect[39m(mid[33m.[39mvx)[33m.[39m[34mtoBeGreaterThan[39m([34m0[39m)[33m;[39m
2026-05-13T07:07:49.5450102Z apps/client test:     [90m   | [39m                   [31m^[39m
2026-05-13T07:07:49.5458064Z apps/client test:     [90m 63| [39m    [90m// Ack everything so the next tick has no inputs in the queue.[39m
2026-05-13T07:07:49.5459973Z apps/client test:     [90m 64| [39m    p[33m.[39m[34mapplyServerSnapshot[39m(
2026-05-13T07:07:49.5461337Z apps/client test: [31m[2m⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/2]⎯[22m[39m
2026-05-13T07:07:49.5463478Z apps/client test: [41m[1m FAIL [22m[49m src/__test__/prediction.test.ts[2m > [22mPredictionEngine[2m > [22mapplyServerSnapshot replays unacked inputs forward from snapshot
2026-05-13T07:07:49.5465457Z apps/client test: [31m[1mAssertionError[22m: expected 0 to be greater than 0[39m
2026-05-13T07:07:49.5466848Z apps/client test: [36m [2m❯[22m src/__test__/prediction.test.ts:[2m112:28[22m[39m
2026-05-13T07:07:49.5469023Z apps/client test:     [90m110| [39m    [34mexpect[39m(afterReplay[33m.[39mx)[33m.[39m[34mtoBeGreaterThan[39m(snap[33m.[39mx)[33m;[39m
2026-05-13T07:07:49.5472596Z apps/client test:     [90m111| [39m    [34mexpect[39m(p[33m.[39m[34mgetUnackedCount[39m())[33m.[39m[34mtoBe[39m([34m2[39m)[33m;[39m
2026-05-13T07:07:49.5474893Z apps/client test:     [90m112| [39m    [34mexpect[39m(afterReplay[33m.[39mvx)[33m.[39m[34mtoBeGreaterThan[39m([34m0[39m)[33m;[39m
2026-05-13T07:07:49.5476516Z apps/client test:     [90m   | [39m                           [31m^[39m
2026-05-13T07:07:49.5477562Z apps/client test:     [90m113| [39m  })[33m;[39m
2026-05-13T07:07:49.5478701Z apps/client test:     [90m114| [39m
2026-05-13T07:07:49.5479761Z apps/client test: [31m[2m⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[2/2]⎯[22m[39m
2026-05-13T07:07:49.5481340Z apps/client test: [2m Test Files [22m [1m[31m1 failed[39m[22m[2m | [22m[1m[32m23 passed[39m[22m[90m (24)[39m
2026-05-13T07:07:49.5483402Z apps/client test: [2m      Tests [22m [1m[31m2 failed[39m[22m[2m | [22m[1m[32m181 passed[39m[22m[2m | [22m[90m4 todo[39m[90m (187)[39m
2026-05-13T07:07:49.5484806Z apps/client test: [2m   Start at [22m 07:07:29
2026-05-13T07:07:49.5486548Z apps/client test: [2m   Duration [22m 19.93s[2m (transform 900ms, setup 61ms, collect 1.38s, tests 857ms, environment 11.54s, prepare 2.25s)[22m
2026-05-13T07:07:49.5491133Z apps/client test: ::error file=/home/runner/work/rebno/rebno/apps/client/src/__test__/prediction.test.ts,title=src/__test__/prediction.test.ts > PredictionEngine > predictTick after ack-and-empty-queue applies pure friction decay,line=62,column=20::AssertionError: expected 0 to be greater than 0%0A ❯ src/__test__/prediction.test.ts:62:20%0A%0A
2026-05-13T07:07:49.5499319Z apps/client test: ::error file=/home/runner/work/rebno/rebno/apps/client/src/__test__/prediction.test.ts,title=src/__test__/prediction.test.ts > PredictionEngine > applyServerSnapshot replays unacked inputs forward from snapshot,line=112,column=28::AssertionError: expected 0 to be greater than 0%0A ❯ src/__test__/prediction.test.ts:112:28%0A%0A
2026-05-13T07:07:49.6805021Z apps/client test: Failed
2026-05-13T07:07:49.6926215Z /home/runner/work/rebno/rebno/apps/client:
2026-05-13T07:07:49.6930115Z  ERR_PNPM_RECURSIVE_RUN_FIRST_FAIL  @rebno/client@0.1.0 test: `vitest run --exclude 'test/e2e/**'`
2026-05-13T07:07:49.6931654Z Exit status 1
2026-05-13T07:07:49.7115316Z 
2026-05-13T07:07:49.7116566Z verify-phase-4 FAILED at step 'Workspace: test': pnpm -r test (exit 1)
2026-05-13T07:07:49.7117576Z Fix the failing step and re-run `pnpm verify:phase-4`.
2026-05-13T07:07:49.7285687Z  ELIFECYCLE  Command failed with exit code 1.
2026-05-13T07:07:49.7499624Z ##[error]Process completed with exit code 1.
